//+------------------------------------------------------------------+
//|                                                        trend.mq4 |
//|                                         Dimitri Rudel 28.10.2013 |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Dimitri Rudel 15.12.2013"
#property link      ""

#include <basic3.mqh>
#include <tradeManager.mqh>


//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+

extern string TRENDSETTINGS = "TRENDSETTINGS";
extern int exCntMinBar = 10;
extern int exCntBreak = 0;
extern double exTakeProfit = 100;
extern double exRetracement = 0.28;
extern double exAdx = 14;
extern double exMinAdx = 25;
extern double exMaxSlp = 0.04;//bei 1.32 50 pips
extern int exMagicNumber = 1000;

extern double exMinMove = 0.0008;
extern double exMaxMove = 0.0015;

extern int exLongTf = 30;
int shortTf;

extern int exMa = 30;

int timeFrame[2];



//trend varsf


datetime oldTime[2];
datetime oldTimeBase;
int trend[2];



int cntTrend[2];
int cntBreak[2];
int cntLow[2];
int cntHigh[2];

double high[2];
double low[2];
double tmpLow[2];
double tmpHigh[2]; 


datetime dtHigh[2];
datetime dtLow[2];

double move = 0;  
double retracement[2];
//voll assi


int cntOpenedTrade = 0;

bool broken = false;



string lastPoint[2];
bool newPoint[2];

//other vars
double adx;
int magicNumber;

//draw vars
double gap = 160;


bool initTrend = false;
int init()
  {
      shortTf = Period();
      magicNumber = exMagicNumber;
      magicNumber += Period();
      Print("trend");
      Print("timeFrame: ",Period());
      Print("magicNumber: ",magicNumber);
      fake();  
      oldTimeBase = Time[0];
   return(0);
  }
  
void initTrend(int tfi, int tf){
      
      timeFrame[tfi] = tf;
      oldTime[tfi] = iTime(0,tf,0);
      trend[tfi] = -1;     
      
      cntTrend[tfi] = 1;
      cntBreak[tfi] = 0;
      cntLow[tfi] = 1;
      cntHigh[tfi] = 1;
      
      dtHigh[tfi] = iTime(0,tf,0);
      dtLow[tfi] = iTime(0,tf,0);
      low[tfi] = iLow(0,tf,iLowest(0,tf,0,MODE_LOW,iBars(0,tf)-1));
      high[tfi] = iHighest(0,tf,iHighest(0,tf,0,MODE_HIGH,iBars(0,tf)-1));

      tmpLow[tfi] = low[tfi];
      tmpHigh[tfi] = high[tfi];    
      
      lastPoint[tfi] = "null";
      newPoint[tfi] = false;
  }
  

int start(){

    if(oldTimeBase == Time[0]){
        return(0);   
    }    
    oldTimeBase =  Time[0];
   
   if(!initTrend && Bars > exCntMinBar){
      initTrend(0, shortTf);
      initTrend(1, exLongTf);
      initTrend = true;
   }if(!initTrend){
      return (0);
   }
   
   if(exDebug){
      drawVars();
   }
   int oldBreak = cntBreak[0];
   
   bool newTrend = startTrend(0);
   if(newTrend){
      //b_OrderDeleteByMagic(magicNumber);
   }
   bool newBreak = !(cntBreak[0] == oldBreak);
   
   //startTrend(1);
   //newPoint[0] = true;

     for(int i=0; i < OrdersTotal() && newPoint[0]; i++) {
         if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
              if ( OrderSymbol()==Symbol() && OrderMagicNumber() == magicNumber) {
                  double price2;
                  double sl2;
                  double tp2;
                   if(OrderType() == OP_BUY && lastPoint[0] == "low"){
                     price2 = Ask;
                     sl2 = low[0] - (Ask - Bid);
                     if(price2 - sl2 > exMaxSlp * price2){
                        sl2 = price2 - (price2 * exMaxSlp);
                     }  

      
                   }else if(OrderType() == OP_SELL && lastPoint[0] == "high"){
                     price2 = Bid;
                     sl2 = high[0] + (Ask - Bid);
                     if(sl2-price2 > exMaxSlp * price2){
                        sl2 = price2 + (price2 * exMaxSlp);
                     }  
 
                   }  
                   else{
                     break;
                   }   

                   b_OrderModify(OrderTicket(),OrderOpenPrice(),sl2,OrderTakeProfit(),0,Blue); 
                        
              }
         }
     }
     //b_modifyByVoigt(magicNumber);
     
     
     //bool newTrade = newPoint[0] && b_isTradeTime() && exCntBreak == cntBreak[0];// && cntBreak[0] == 0 ;//&& trend[0] == trend[1]; 
     bool newTrade =  newTrend && b_isTradeTime() ;//&& trend[0] == trend[1]
     if(newTrade){
         double ma = iMA(0,0,exMa,1,MODE_SMMA,PRICE_CLOSE,1);
         b_OrderDeleteByMagic(magicNumber);
         
         double price = 0;
         double sl = 0;
         int cmd = -1;
         double tp;       
         if(trend[0] == 0 ){
            price = high[0] + Ask - Bid;
            sl = low[0] - (Point * (Ask-Bid));
            cmd = OP_BUYSTOP;
            if(price - sl > exMaxSlp * price){
               sl = price - (price * exMaxSlp);
            }  
            tp = price + Point * exTakeProfit;

         }else if(trend[0] == 1 ){
            price = low[0];
            cmd = OP_SELLSTOP;
            sl = high[0] + Point * (Ask-Bid);
            
            if(sl - price > exMaxSlp * price){

               sl = price + (price * exMaxSlp);
            }
            tp = price - Point * exTakeProfit;

         }else{
            return(1);
         }

         tp = 0;
         b_OrderSend(Symbol(),cmd,0.1,price,3,sl,tp,"trend["+magicNumber+"]",magicNumber,0); 

     }
}
  

bool startTrend(int tfi)
  {   
     int tf = timeFrame[tfi];
     newPoint[tfi] = false; 
     bool newTrend = false;
      //todo !!
     if(oldTime[tfi] == iTime(0,tf,0)){
         return(0);   
     }    
     oldTime[tfi] = iTime(0,tf,0);
     
     
     
     if(trend[tfi] != 1 && iLow(0,tf,1) < low[tfi])
     {  
       trend[tfi] = 1; 
       drawV(iTime(0,tf,1),"DOWN"+cntTrend[tfi]+" tf:"+tf);
       cntTrend[tfi]++;
       cntBreak[tfi] = 0;
       newTrend = true;

     }else if(trend[tfi] != 0 && iHigh(0,tf,1) > high[tfi])
     {
    
       trend[tfi] = 0; 
       drawV(iTime(0,tf,1),"UP"+cntTrend[tfi]);
       cntTrend[tfi]++; 
       cntBreak[tfi] = 0;
       newTrend = true;

     }
     if(newTrend){
         retracement[tfi] = 0;
     }



     bool newHigh = false;
     bool newLow = false;
 
     if(iLow(0,tf,1) < tmpLow[tfi]){
         tmpLow[tfi] = iLow(0,tf,1);
         dtLow[tfi] = iTime(0,tf,1);
         cntLow[tfi]++;
         newLow = true;             
     }    

     if(iHigh(0,tf,1) > tmpHigh[tfi]){
         tmpHigh[tfi] = iHigh(0,tf,1);
         dtHigh[tfi] = iTime(0,tf,1);
         cntHigh[tfi]++;
         newHigh = true; 
     }
     
     double move = tmpHigh[tfi] - tmpLow[tfi];
     if(newHigh){
         //drawA(tmpHigh + gap * Point,dtHigh,"high: "+cntHigh+" move: "+move, SYMBOL_ARROWUP, Orange); 
         
    
         
         
         if(trend[tfi] == 0){
         
            
                  
            if(tmpHigh[tfi] > high[tfi]  && lastPoint[tfi] != "low" && tmpLow[tfi] * exMinMove <= move){

               drawA(tmpLow[tfi] - gap * Point,dtLow[tfi],"low: "+cntLow[tfi]+" retracement: "+retracement[tfi]+" tf"+tf, SYMBOL_ARROWDOWN, Red);
               low[tfi] = tmpLow[tfi];
               lastPoint[tfi] = "low";
               newPoint[tfi] = true;
               cntBreak[tfi]++;
            } 

            tmpLow[tfi] = iHigh(0,tf,1);
            dtLow[tfi] = iTime(0,tf,1);

         }else{
            move = high[tfi] - tmpLow[tfi];
            retracement[tfi] = 0;
            if(move > 0){
               retracement[tfi] = (tmpHigh[tfi] - tmpLow[tfi])/move;
            }
            if(((((tmpHigh[tfi] - low[tfi])/tmpHigh[tfi] > exMaxMove) || (retracement[tfi]) >= exRetracement)) && lastPoint[tfi] != "low"){
               if(low[tfi] != tmpLow[tfi]){
                  
                  drawA(tmpLow[tfi] - gap * Point,dtLow[tfi],"low: "+cntLow[tfi]+" move: "+retracement[tfi] +" tf"+tf, SYMBOL_ARROWDOWN, Red);
                  //hier ist tmpLow 0;
                                 
                  low[tfi] = tmpLow[tfi];
                  
                  lastPoint[0] = "low";
                  newPoint[tfi] = true; 
               }
            }
         }
     }else if(newLow){
         if(trend[tfi] == 0){
            move = tmpHigh[tfi] - low[tfi];
            retracement[tfi] = 0;
            if(move > 0){
               retracement[tfi] = (tmpHigh[tfi] - tmpLow[tfi])/(move);
            }
            if((((high[tfi] - tmpLow[tfi])/tmpLow[tfi] > exMaxMove) ||(retracement[tfi] >= exRetracement)) && lastPoint[tfi] != "high"){           
               if(high[tfi] != tmpHigh[tfi]){
                  
                  drawA(tmpHigh[tfi] + gap * Point,dtHigh[tfi],"high: "+cntHigh[tfi]+" move: "+retracement[tfi]+" tf"+tf, SYMBOL_ARROWUP, Green);
                  high[tfi] = tmpHigh[tfi]; 
                  lastPoint[tfi] = "high";
                  newPoint[tfi] = true;
               }       
            }    
         }else{
            if(tmpLow[tfi] < low[tfi] && lastPoint[tfi] != "high" && tmpHigh[tfi] * exMinMove <= move){

                  drawA(tmpHigh[tfi] + gap * Point,dtHigh[tfi],"high: "+cntLow[tfi]+" Retracement: "+retracement[tfi] +" tf"+tf, SYMBOL_ARROWUP, Green);
                  high[tfi] = tmpHigh[tfi];
                  lastPoint[tfi] = "high";
                  newPoint[tfi] = true;
                  cntBreak[tfi]++;
            } 
              tmpHigh[tfi] = iHigh(0,tf,1);
              dtHigh[tfi] = iTime(0,tf,1);
         }
         //drawA(tmpLow - gap * Point,dtLow,"low: "+cntLow+" Retracement: "+retracement, SYMBOL_ARROWDOWN, Orange); 
     }
     if(newTrend){
      cntBreak[tfi] = 0;
     }
     return (newTrend);

}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
  
void drawVars(){
   if(!exDebug){
      return (0);
   }
   int row = 1;
   row = draw_new_row("trend0",trend[0],row);
   row = draw_new_row("high",DoubleToStr(high[0],Digits),row);
   row = draw_new_row("low",DoubleToStr(low[0],Digits),row); 
   row = draw_new_row("cntBreak",cntBreak[0],row); 
   row++; 
   row = draw_new_row("trend1",trend[1],row);
   row = draw_new_row("high",DoubleToStr(high[1],Digits),row);
   row = draw_new_row("low",DoubleToStr(low[1],Digits),row);
   row = draw_new_row("tmpLow",DoubleToStr(tmpLow[1],Digits),row);
}
  
void drawA(double price,datetime dt,string name = "arrow", int arrowCode = SYMBOL_ARROWUP, color col = Black){  
   if(!exDebug){
      return (0);
   }
   ObjectCreate(name,OBJ_ARROW,0,dt,price);  
   ObjectSet(name,OBJPROP_COLOR,col);
   ObjectSet(name,OBJPROP_STYLE,STYLE_SOLID); 
   ObjectSet(name, OBJPROP_ARROWCODE, arrowCode);
}

void drawV(datetime dt,string name = "line",color col = Black){ 
   if(!exDebug){
      return (0);
   } 
   
   ObjectCreate(name,OBJ_VLINE,0,dt,0);
   ObjectSet(name,OBJPROP_STYLE,STYLE_DOT);  
   ObjectSet(name,OBJPROP_COLOR,col);
}
  
void drawH(double price,string name = "line",int type = OBJ_HLINE, color col = Black){
   if(!exDebug){
      return (0);
   }     
   ObjectDelete(name);
   ObjectCreate(name,OBJ_HLINE,0,0,price);
   ObjectSet(name,OBJPROP_STYLE,STYLE_DASH);  
   ObjectSet(name,OBJPROP_COLOR,col);
}



int draw_new_row(string col1, string col2,int row)
{
   if(!exDebug){
      return (0);
   }
   string objName = "a"+row;
   color c= Black;
   int corner_position = 1;
   int fontsize = 16;
   int col1_xdist = 50;
   int y_offset = 5;
   int col2_xdist = 2;
   string fontname = "Times New Roman";


   ObjectCreate(objName,OBJ_LABEL,0,0,0);
   ObjectSet(objName,OBJPROP_CORNER,corner_position);
   ObjectSet(objName,OBJPROP_XDISTANCE,col1_xdist+(fontsize*2.7));
   ObjectSet(objName,OBJPROP_YDISTANCE,row*(fontsize+2)+y_offset+50);
   ObjectSetText(objName,col1,fontsize,fontname,c);
        

   objName = "b"+row;

   c=Red;

   ObjectCreate(objName,OBJ_LABEL,0,0,0);
   ObjectSet(objName,OBJPROP_CORNER,corner_position);
   ObjectSet(objName,OBJPROP_XDISTANCE,col2_xdist);
   ObjectSet(objName,OBJPROP_YDISTANCE,row*(fontsize+2)+y_offset+50);
   ObjectSetText(objName,col2,fontsize,fontname,c);
        
   return(row+1);
}
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+